home *** CD-ROM | disk | FTP | other *** search
- /* HyperCard XFCN that returns information on the index key
- * record number N in the (already opened) key file F ... called as:
- * getKeyRecord ( N, F)
- * where N is 0-based, and F is a refNum value returned by
- * the XFCN openFile() ....
- *
- * The results are returned as a nice comma-delimited string consisting of:
- * the number of the first ptr record for this key;
- * the number of occurrences of the key;
- * the item's key word, KEY_LENGTH characters long (padded on the right
- * by trailing blanks as necessary).
- * If there has been a mistake, a null string is returned and the function
- * also emits a beep....
- *
- * Function is stored as XFCN number 300, named "getKeyRecord"....
- *
- * The key file must in the standard ^z browser format as created
- * by qndxr....
- *
- * 871208 ^z
- */
-
- #include <MacTypes.h>
- #include <FileMgr.h>
- #include <OSUtil.h>
- #include <HyperXCmd.h>
- #include <proto.h>
-
- #define KEY_LENGTH 28 /* default choice in building indices */
- typedef struct
- {
- char kkey[KEY_LENGTH];
- long ccount;
- } KEY_REC;
-
-
- pascal void main (XCmdBlockPtr paramPtr);
- void getKeyRec (KEY_REC *recp, long recNum, int refNum);
- int putNum (char *ans, long count);
- void complain (XCmdBlockPtr paramPtr);
-
-
- pascal void main (paramPtr)
- XCmdBlockPtr paramPtr;
- {
- KEY_REC this_rec, prev_rec;
- int refNum0, i, j;
- long indexRecNum;
- Handle answer;
-
- if (paramPtr->paramCount != 2)
- {
- complain (paramPtr);
- return;
- }
-
- indexRecNum = atol (*(paramPtr->params[0]));
- refNum0 = atol (*(paramPtr->params[1]));
-
- if (indexRecNum < 0 || refNum0 == 0)
- {
- complain (paramPtr);
- return;
- }
-
- answer = NewHandle (256);
- getKeyRec (&prev_rec, indexRecNum - 1, refNum0);
- getKeyRec (&this_rec, indexRecNum, refNum0);
- i = putNum (*answer, prev_rec.ccount);
- *(*answer + i++) = ',';
- j = putNum (*answer + i, this_rec.ccount - prev_rec.ccount);
- i += j;
- *(*answer + i++) = ',';
- for (j = 0; j < KEY_LENGTH; ++j)
- *(*answer + i++) = this_rec.kkey[j];
- *(*answer + i) = '\0';
-
- paramPtr->returnValue = answer;
- return;
- }
-
-
- /* function to fetch the requested index record from the file ...
- * note that if an illegal recNum is asked for, it
- * returns 0 for ccount and a blank kkey....
- */
-
- void getKeyRec (recp, recordNum, refNum)
- KEY_REC *recp;
- long recordNum;
- int refNum;
- {
- long count;
- int i;
-
- count = sizeof(KEY_REC);
-
- if (recordNum < 0 ||
- SetFPos (refNum, fsFromStart,
- recordNum * sizeof(KEY_REC)) != noErr ||
- FSRead (refNum, &count, recp) != noErr)
- {
- for (i = 0; i < KEY_LENGTH; ++i)
- recp->kkey[i] = ' ';
- recp->ccount = 0;
- }
-
- return;
- }
-
-
-
- /* function to convert a number into a string and put it into the chosen
- * target place ... returns the number of characters stored ...
- * based on K&R p. 60 example of itoa()....
- */
-
- int putNum (ans, num)
- char *ans;
- long num;
- {
- int i, j, s, result;
-
- i = 0;
- s = 1;
- if (num < 0)
- {
- num = -num;
- s = -1;
- }
-
- do
- ans[i++] = num % 10 + '0';
- while ((num /= 10) > 0);
-
- if (s < 0)
- ans[i++] = '-';
- result = i;
-
- for (--i, j = 0; j < i; ++j, --i)
- {
- s = ans[i];
- ans[i] = ans[j];
- ans[j] = s;
- }
-
- return (result);
- }
-
-
- /* function to beep and set the return string to null (= "")
- */
-
- void complain (paramPtr)
- XCmdBlockPtr paramPtr;
- {
- Handle answer;
-
- SysBeep (10);
- answer = NewHandle (1);
- **answer = '\0';
- paramPtr->returnValue = answer;
- return;
- }
-
-
-
- /* function to convert alphabetic string to a long integer ... from LSC
- * library.... simplified to avoid using isspace() & isdigit() ....
- */
-
- long atol (s)
- register char *s;
- {
- register char signflag = 0;
- register long r = 0;
-
- while ((*s == ' '))
- s++;
-
- if (*s == '-')
- {
- signflag = 1;
- s++;
- }
- else if (*s == '+')
- s++;
-
- while (*s >= '0' && *s <= '9')
- r = r * 10 + (*s++ - '0');
-
- return (signflag ? -r : r);
- }
-
-